<template>
  <div class="CarTrace" v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(255, 255, 255, 0.6)">
    <div class="main">
      <el-form :inline="true" :model="row" class="demo-form-inline">
      <el-form-item label="司机姓名">
        <el-input v-model="row.sjxm" placeholder="司机姓名" readonly></el-input>
      </el-form-item> 
      <el-form-item label="车牌号">
        <el-input v-model="row.cph" placeholder="车牌号" readonly></el-input>
      </el-form-item> 
      <el-form-item label="手机号">
        <el-input :value="row.mobile_display || row.phone" placeholder="手机号" readonly></el-input>
      </el-form-item> 
      <el-button @click="exportDataToExcel" type="primary">导出轨迹</el-button>
    </el-form>
      <div ref="qqmap" class="map" id="qqmap"></div>
      <el-card class="box-card">
        <el-button round class="btn" @click="palyAni">播放动画</el-button>
        <el-button round class="btn" @click="pauseAni">暂停动画</el-button>
        <el-button round class="btn" @click="restartAni">重新播放</el-button>
      </el-card>
    </div>
    <div class="right" style="display: none;">
      <h2 class="title">途径路线</h2>
      <el-timeline>
        <el-timeline-item v-for="(item, index) in mapPoints" :key="index" :timestamp="item.time">{{ item.des
          }}</el-timeline-item>
      </el-timeline>
    </div>
  </div>
</template>

<script>
// import { carPosition } from "@/api/public";
// import { carTraceData } from "@/utils/mockData.js";
// import { deepClone } from "@/utils/tool.js";
// window.cb = (ret) => {

// }
import {carPositionAddress} from '@/api/shipper';
import { getHeader,exportDataToExcel,deepClone } from '@/utils/tool';
import axios from 'axios'
export default {
  name: "CarTrace",
  props: ['id','row'],
  data() {

    function callBack(data) {
      // console.log(data.result.routes[0].polyline);
      // console.log(data.result.routes[0].polyline);
      var coors = data.result.routes[0].polyline;
      for (var i = 2; i < coors.length; i++) { coors[i] = coors[i - 2] + coors[i] / 1000000 }
      let arr = [];
      coors.forEach((item, index) => {
        if (index % 10 === 0 && index !== 0) {
          arr.push({
            lat: item,
            lng: coors[index - 1]
          })
        }
      });
      this.linePlanDraw(arr)
    }
    window.cbPosition = callBack.bind(this)
    return {
      endCarInfo:{},
      mapPoints: [],
      mapPointsData:[],
      traceMap: null,
      traceMarker: null,
      loading: false,
      to_addressPosition: {
        lat: "",
        lng: ""
      },
      linePlanPoints: [],
    };
  },
  mounted() {
    //接口等待时间过长 暂时用模拟数据
    // carPosition({
    //   id: 228757
    // }).then(res => {
    //   if (res.code == 200) {
    //     this.mapPoints = res.arr;
    //     this.initMap();
    //   }
    // });
    this.getPoints();
  },
  methods: {
    async getPoints() {
      this.loading = true;
      axios({
        url: `https://api.zhgylgl.com/api/shipper/carPosition?id=${this.id}`,
        methods: 'get',
        headers: getHeader()
      }).then(res => {
        this.loading = false;
        if (res.data.code == 200 && res.data.data.length > 1) {
          this.mapPoints = res.data.data; 
          this.mapPointsData = deepClone(this.mapPoints);   
          this.to_addressPosition = res.data.extra;
          this.initMap();
        } else if (res.data.code == 316) {
          this.$message.error(res.data.msg)
        } else if (res.data || !res.data.data.length > 1) {
          this.$message.error('暂无数据')
        }
      })
    },

    //导出轨迹
    async exportDataToExcel(){
      let data = this.mapPointsData;
      if (data.length === 0) {
        this.$message.warning("暂无数据可导出");
        return;
      }
      // 如果数据少于 50 条，直接导出
      let exportData = data;
      if (data.length >= 50) {
        const step = Math.floor((data.length - 1) / 49); // 确保保留起点和终点
        exportData = [];

        for (let i = 0; i < data.length; i += step) {
          exportData.push(data[i]);
        }

        // 确保最后一个元素是终点
        if (exportData[exportData.length - 1] !== data[data.length - 1]) {
          exportData.push(data[data.length - 1]);
        }
      }
      let loading = this.$setLoading('数据量较大,正在导出中...');
      let result = await carPositionAddress(exportData);
      loading.close();
      if(result.code == 200){
         // 格式转换
        const worksheetData = result.data.map(item => ({
          "经度": item.lon,
          "纬度": item.lat,
          "时间": item.time,
          "详细地址": item.des,
        }));
        let name = `${this.row.add_id}-${this.row.id} 车辆轨迹信息`;
        let sheetDes = `车辆轨迹`;
        exportDataToExcel(worksheetData,name,sheetDes)
      }
    },
    initMap() {
      // this.mapPoints = deepClone(carTraceData);
      // this.mapPoints = this.list;
      let center = new TMap.LatLng(39.984104, 116.307503); //设置中心点坐标
      //初始化地图
      this.traceMap = new TMap.Map(this.$refs.qqmap, {
        center: center,
        mapStyleId: "style1",
        // minZoom: 1, //此处设置地图的缩放级别  最小值是6
        // maxZoom: 20, //此处设置地图的缩放级别  最大值是7
        zoom: 12
      });
      var endCar = this.mapPoints[0];
      this.endCarInfo = endCar;
      var start = this.mapPoints[this.mapPoints.length - 1];
      //计算距离
      var startPoint = new TMap.LatLng(start.lat, start.lon);
      var endPoint = new TMap.LatLng(endCar.lat, endCar.lon);
      this.linePlan(endCar)
      // 计算路径的实际距离 用于优化速度 单位为米
      var distance = TMap.geometry.computeDistance([startPoint, endPoint]);

      //小车移动路线
      let reverseList = deepClone(this.mapPoints).reverse();
      
      var path = reverseList.map(item => {
        return new TMap.LatLng(item.lat, item.lon);
      });


      //创建LatLngBounds实例
      var latlngBounds = new TMap.LatLngBounds();
      //将坐标逐一做为参数传入extend方法，latlngBounds会根据传入坐标自动扩展生成
      //将起始点向左偏移一下
      let boundsPath = [new TMap.LatLng(start.lat, start.lon), endPoint];
      for (let i = 0; i < path.length; i++) {
        //添加弹框用于截取某段路线
      //   if(i % 10 == 0){
      //     //根据终点位置坐标画出信息框  
      //     let infoWindowLocation = path[i];//创建一个坐标
      //     //创建InfoWindow实例，并进行初始化
      //     let infowindow = new TMap.InfoWindow({
      //       content:"My location", //信息窗口内容
      //       position:infoWindowLocation,//显示信息窗口的坐标
      //       map:this.traceMap,
      //       offset: { x: 0, y: -45 }, //设置信息窗相对position偏移像素，为了使其显示在Marker的上方
      //       content:`<div class='endWindow'>
      //         <p class='item'> ${i}</p>
      //         <p class='item'><span>上报时间 :</span>${reverseList[i].time}</p>
      //         <p class='item'><span>当前位置 :</span>${reverseList[i].des}</p>
      //         </div>`
      //     });
      //     // console.log('infowindow',infowindow);
          
      //     infowindow.open();  
      //   }


        latlngBounds.extend(path[i]);
      }
      //调用fitBounds自动调整地图显示范围
      this.traceMap.fitBounds(latlngBounds);

      var polylineLayer = new TMap.MultiPolyline({
        map: this.traceMap, // 绘制到目标地图
        // 折线样式定义
        styles: {
          style_blue: new TMap.PolylineStyle({
            color: "#2e7dff", // 线填充色
            // width: 2, // 折线宽度
            // borderWidth: 2, // 边线宽度
            // borderColor: "#FFF", // 边线颜色
            // lineCap: "round", // 线端头方式
            // eraseColor: "rgba(190,188,188,1)"
            // 'color': '#21b977', //线填充色
            'width': 4, //折线宽度
            'borderWidth': 2, //边线宽度
            'borderColor': '#5994eb', //边线颜色
            'lineCap': 'round', //线端头方式
            'showArrow': true,
            'eraseColor': "#21b977"
          })
        },
        geometries: [
          {
            id: "erasePath",
            styleId: "style_blue",
            paths: path
          }
        ]
      });
      //创建mareker（小车）
      this.traceMarker = new TMap.MultiMarker({
        map: this.traceMap,
        styles: {
          "car-down": new TMap.MarkerStyle({
            width: 40,
            height: 40,
            anchor: {
              x: 20,
              y: 20
            },
            faceTo: "map",
            rotate: 180,
            src: "https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/car.png"
          }),
          start: new TMap.MarkerStyle({
            width: 25,
            height: 35,
            anchor: { x: 16, y: 32 },
            src: "https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/start.png"
          }),
          current: new TMap.MarkerStyle({
            width: 25,
            height: 35,
            anchor: { x: 16, y: 32 },
          }),
          end: new TMap.MarkerStyle({
            width: 25,
            height: 35,
            anchor: { x: 16, y: 32 },
            src: "https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/end.png"
          })
        },
        geometries: [
          {
            id: "car",
            styleId: "car-down",
            position: new TMap.LatLng(start.lat, start.lon)
          },
          {
            id: "start",
            styleId: "start",
            position: new TMap.LatLng(start.lat, start.lon)
          },
          {
            id: "current",
            styleId: "current",
            position: new TMap.LatLng(endCar.lat, endCar.lon)
          },
          {
            id: "end",
            styleId: "end",
            position: new TMap.LatLng(this.to_addressPosition.lat, this.to_addressPosition.lng)
          }
        ]
      });

      this.traceMarker.on("moving", e => {
        var passedLatLngs = e.car && e.car.passedLatLngs;
        if (passedLatLngs) {
          // 使用路线擦除接口 eraseTo, https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocVector
          polylineLayer.eraseTo(
            "erasePath",
            passedLatLngs.length - 1,
            passedLatLngs[passedLatLngs.length - 1]
          );
        }
      });

      //根据终点位置坐标画出信息框  
      var infoWindowLocation = new TMap.LatLng(this.endCarInfo.lat,this.endCarInfo.lon);//创建一个坐标
      //创建InfoWindow实例，并进行初始化
      var infowindow = new TMap.InfoWindow({
        content:"My location", //信息窗口内容
        position:infoWindowLocation,//显示信息窗口的坐标
        map:this.traceMap,
        offset: { x: 0, y: -45 }, //设置信息窗相对position偏移像素，为了使其显示在Marker的上方
        content:`<div class='endWindow'>
          <p class='item'><span>上报时间 :</span>${this.endCarInfo.time}</p>
          <p class='item'><span>当前位置 :</span>${this.endCarInfo.des}</p>
          </div>`
      });
      // infowindow.close();
      //小车走完显示当前点位信息弹框
      this.traceMarker.on("move_ended", e => {
        console.log('小车走完路径啦'); 
        infowindow.open();   
      });
      //点击当前点位显示信息弹框
      this.traceMarker.on("click", e => {
        if(e.geometry.id == 'current'){
          infowindow.open();
        }
      });
      var speed = 1000; //speed为指定速度，正整数，单位：千米/小时
      //计划30秒走完 用当前距离distance除以 30 然后 * 3600 得出speed值
      speed = (distance / 1000 / 10) * 3600;

      //调用moveAlong，实现小车移动
      this.traceMarker.moveAlong(
        {
          car: {
            //设置让"car"沿"path"移动，速度70公里/小时
            path,
            speed: speed
          }
        },
        {
          autoRotation: true //车头始终向前（沿路线自动旋转）
        }
      );

      // //设置延迟 为当前显示的轨迹范围加个边距
      // setTimeout(() => {
      //   let currentZoom = this.traceMap.getZoom();
      //   this.traceMap.setZoom(currentZoom - 0.5);
      // }, 500);
    },
    palyAni() {
      this.traceMarker.resumeMove();
    },
    pauseAni() {
      this.traceMarker.pauseMove();
    },
    restartAni() {
      this.traceMarker.stopMove(); //先暂停轨迹动画然后再销毁 否则报错
      // this.traceMap && this.traceMap.destroy();
      // this.initMap();
      var endCar = this.mapPoints[0];
      var start = this.mapPoints[this.mapPoints.length - 1];
      //计算距离
      var startPoint = new TMap.LatLng(start.lat, start.lon);
      var endPoint = new TMap.LatLng(endCar.lat, endCar.lon);
      // 计算路径的实际距离 用于优化速度 单位为米
      var distance = TMap.geometry.computeDistance([startPoint, endPoint]);
      var speed = 1000; //speed为指定速度，正整数，单位：千米/小时
      //计划30秒走完 用当前距离distance除以 30 然后 * 3600 得出speed值
      speed = (distance / 1000 / 10) * 3600;
      var path = this.mapPoints.map(item => {
        return new TMap.LatLng(item.lat, item.lon);
      });
      //调用moveAlong，实现小车移动
      this.traceMarker.moveAlong(
        {
          car: {
            //设置让"car"沿"path"移动，速度70公里/小时
            path,
            speed: speed
          }
        },
        {
          autoRotation: true //车头始终向前（沿路线自动旋转）
        }
      );
    },
    linePlan(endAddress) {//线路规划到终点
      var url = "https://apis.map.qq.com/ws/direction/v1/driving/"; //请求路径
      url += `?from=${endAddress.lat},${endAddress.lon}`;  //起点坐标
      url += `&to=${this.to_addressPosition.lat},${this.to_addressPosition.lng}`;  //终点坐标
      url += "&output=jsonp&callback=cbPosition";  //指定JSONP回调函数名，本例为cb
      url += "&key=KRABZ-HZWKB-L7YUF-NNWJ2-XEKQ2-XJBNU"; //开发key，可在控制台自助创建
      this.jsonp_request(url);
    },
    jsonp_request(url) {
      var script = document.createElement('script');
      script.src = url;
      document.body.appendChild(script);
    },
    linePlanDraw(arr) {
      var path = arr.map(item => {
        return new TMap.LatLng(item.lat, item.lng);
      });
      var polylineLayer = new TMap.MultiPolyline({
        map: this.traceMap, // 绘制到目标地图
        // 折线样式定义
        styles: {
          style_blue: new TMap.PolylineStyle({
            color: "#2e7dff", // 线填充色
            // width: 2, // 折线宽度
            // borderWidth: 2, // 边线宽度
            // borderColor: "#FFF", // 边线颜色
            // lineCap: "round", // 线端头方式
            // eraseColor: "rgba(190,188,188,1)"
            // 'color': '#21b977', //线填充色
            'width': 4, //折线宽度
            'borderWidth': 2, //边线宽度
            'borderColor': '#5994eb', //边线颜色
            'lineCap': 'round', //线端头方式
            'showArrow': true,
            'eraseColor': "#21b977"
          })
        },
        geometries: [
          {
            id: "erasePath",
            styleId: "style_blue",
            paths: path
          }
        ]
      });


      //创建LatLngBounds实例
      var latlngBounds = new TMap.LatLngBounds();
      //将坐标逐一做为参数传入extend方法，latlngBounds会根据传入坐标自动扩展生成
      //将起始点向左偏移一下
      // let boundsPath = [new TMap.LatLng(start.lat, start.lon), endPoint];
      for (var i = 0; i < path.length; i++) {
        latlngBounds.extend(path[i]);
      }
      this.mapPoints.forEach((item) => {
        latlngBounds.extend(new TMap.LatLng(item.lat, item.lon));
      })
      //调用fitBounds自动调整地图显示范围
      this.traceMap.fitBounds(latlngBounds);


      //设置延迟 为当前显示的轨迹范围加个边距
      setTimeout(() => {
        let currentZoom = this.traceMap.getZoom();
        this.traceMap.setZoom(currentZoom - 0.5);
      }, 500);
    }
  },
  destroy() {
    // console.log('地图组件销毁');
  }
};
</script>

<style lang="scss">
.CarTrace {
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: flex;

  .el-form .el-form-item{
    margin-bottom: 10px;
    margin-right: 20px;
  }
}

.CarTrace .main {
  width: 80%;
  width: 100%;
  height: 100%;
  position: relative;
}

.CarTrace .main .box-card {
  position: absolute;
  z-index: 9999999;
  right: 10px;
  bottom: 10px;
  display: flex;
}

.CarTrace .main .map {
  width: 100%;
  height: 100%;
}

.CarTrace .right {
  padding: 0 10px;
  flex: 1;
  margin-left: 10px;
  overflow: auto;
}

.CarTrace .right .title {
  text-align: left;
  margin-bottom: 10px;
}
.endWindow{
  // width: 150px;
  // height: 50px;
  .item{
    margin-bottom: 5px;
    text-align: left;
    user-select: none;
    span{
      margin-right: 10px;
    }
  }

}

/*# sourceMappingURL=css.css.map */
</style>
